
    /**  
    * @Title: PushEventUtils.java
    * @Package com.efast.cafe.commponent.es.socketio.util
    * @Description: TODO(用一句话描述该文件做什么)
    * @author Administrator
    * @date 2018年10月31日
    * @version V1.0  
    */
    
package com.efast.cafe.commponent.es.socketio.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import com.cafeauto.socketio.SocketIOData;
import com.efast.cafe.commponent.log.ext.CafeLogger;
import com.efast.cafe.commponent.log.ext.CafeLoggerFactory;
import com.efast.cafe.framework.constant.FrameConstant;
import com.efast.cafe.framework.exception.ServiceException;
import com.efast.cafe.framework.json.JSONObject;
import com.efast.cafe.util.date.DateUtils;

/**
    * @ClassName: PushEventUtils
    * @Description: 消息推送 
    * @author Administrator
    * @date 2018年10月31日
    *
    */
@Component
public class SocketEventUtils {
	
	static CafeLogger logger = CafeLoggerFactory.getLogger(SocketEventUtils.class);

	@Autowired
	private StringRedisTemplate template;
	
	/**
	 * 
	    * @Title: pushMessage
	    * @Description: 给指定设备推送消息
	    * @param @param uid 设备id
	    * @param @param eventName 事件名称
	    * @param @param busObject    推送数据
	    * @return void    返回类型
	    * @throws
	 */
	public void pushMessage(String uid, String eventName, String busObject){
		if(checkOnline(uid)){
				SocketIOData data = new SocketIOData();
				data.setId(UUID.randomUUID().toString().replaceAll("-", "") + 
						DateUtils.format(new Date(), DateUtils.FORMAT_DATE_YYYYMMDDHHMM_SSSSS));
				data.setEventName(eventName);
	            data.setBusObject(busObject);
	            data.setUid(uid);
	            String dataStr = new JSONObject(data).toString();
	            template.convertAndSend(SocketIOUtil.SOCKET_MESSAGE_KEY_ +uid, dataStr);
			logger.info("Event:"+eventName+",设备："+uid+",成功推送至客户端消息："+dataStr);
		}else{
			throw new ServiceException("USER_OFF_LINE");
		}
		
	}

	
	   
	
	/**
	 * 
	    * @Title: checkOnline
	    * @Description: 根据设备uid校验设备是否在线
	    * @param @param uid
	    * @param @return    参数
	    * @return boolean    返回类型
	    * @throws
	 */
	public  boolean checkOnline(String uid){
		List<Object> keys = template.opsForHash().values(FrameConstant.SOCKET_IO_INSTANT);
		HashOperations<String, Object, Object> ops = template.opsForHash();
		for(Object instant:keys){
			boolean hasKey = ops.hasKey(FrameConstant.SOCKET_IO_ONLINE_TOKEN+":"+instant.toString(), uid);
			if(hasKey){
				return true;
			}
		}
		return false;
	}
	
	
	/**
	 * 
	    * @Title: getAllOnline
	    * @Description: 获取所有在线设备uid集合
	    * @param @return    参数
	    * @return List<String>    返回类型
	    * @throws
	 */
	public  List<String> getAllOnline(){
		List<Object> keys = template.opsForHash().values(FrameConstant.SOCKET_IO_INSTANT);
		List<String> keyList = new ArrayList<>();
		HashOperations<String, Object, Object> ops = template.opsForHash();
		keys.forEach(instant->{
			Set<Object> sets = ops.keys(FrameConstant.SOCKET_IO_ONLINE_TOKEN+":"+instant.toString());
			sets.forEach(key->{
				keyList.add(key.toString());
			});
		});
		return keyList;
	}
	
	/**
	 * 
	    * @Title: disconnectUID
	    * @Description:断开某设备长连接
	    * @param @param uid    设备ID 
	    * @return void    返回类型
	    * @throws
	 */
	public  void disconnectUID(String uid){
		pushMessage(uid,FrameConstant.SOCKET_DISCONNECT_EVENT,null);
		logger.info("服务端主动断开设备连接："+uid);
	}
}
